package com.jourwon.spring.boot.respsonse;

import com.alibaba.fastjson.JSON;
import com.jourwon.spring.boot.query.QuerySearchAfter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * SearchAfter响应参数
 *
 * @author JourWon
 * @date 2024/3/11
 */
@Getter
@Setter
@ApiModel(value = "SearchAfter响应参数")
public final class ResponseSearchAfter<T> {

    @ApiModelProperty(value = "具体结果数据")
    private SearchAfterContent<T> content;

    @ApiModelProperty(value = "总数")
    private Long totalElements;

    @ApiModelProperty(value = "总页数")
    private Integer totalPages;

    private ResponseSearchAfter() {
        this.content = SearchAfterContent.ofEmpty();
        this.totalElements = null;
        this.totalPages = null;
    }

    public static <T> ResponseSearchAfter<T> ofEmpty(QuerySearchAfter qo) {
        final ResponseSearchAfter<T> responseSearchAfter = new ResponseSearchAfter<>();
        responseSearchAfter.getContent().setLastSortIdMap(qo.getLastSortIdMap());

        return responseSearchAfter;
    }

    public static <T> ResponseSearchAfter<T> ofSuccess(QuerySearchAfter qo, String nextSortId, List<T> list, Long totalElements) {
        ResponseSearchAfter<T> responseSearchAfter = new ResponseSearchAfter<>();

        responseSearchAfter.setContent(SearchAfterContent.ofSuccess(nextSortId, list, qo.getLastSortIdMap()));
        responseSearchAfter.setTotalElements(totalElements);
        if (Objects.nonNull(totalElements) && totalElements != 0) {
            Integer totalPages = (int) (totalElements + qo.getSize() - 1) / qo.getSize();
            responseSearchAfter.setTotalPages(totalPages);
        }

        return responseSearchAfter;
    }

    /**
     * SearchAfter查询具体结果数据
     *
     * @param <T>
     */
    @Getter
    @Setter
    public static final class SearchAfterContent<T> {

        @ApiModelProperty(value = "每一页的排序ID记录,key=页码,value=sortId")
        private Map<String, String> lastSortIdMap;

        @ApiModelProperty(value = "下一次查询请求的排序ID")
        private String nextSortId;

        @ApiModelProperty(value = "查询结果数据")
        private List<T> data;

        private SearchAfterContent() {
            this.nextSortId = null;
            this.data = Collections.emptyList();
        }

        public static <T> SearchAfterContent<T> ofEmpty() {
            return new SearchAfterContent<>();
        }

        public static <T> SearchAfterContent<T> ofSuccess(String nextSortId, List<T> list, Map<String, String> lastSortIdMap) {
            SearchAfterContent<T> data = new SearchAfterContent<>();

            data.setNextSortId(nextSortId);
            data.setData(list);
            data.setLastSortIdMap(lastSortIdMap);

            return data;
        }
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }

}
